'''
Created on Apr 6, 2011

Generic Module for Different Types of Controlled Terminology

@author: glow
'''

from google.appengine.ext import db
from google.appengine.ext.db import polymodel

from django.conf import settings

class Organisation(db.Model):
  """
  Examples ISO, CDISC
  """
  name = db.StringProperty('Organisation Name')
  url = db.URLProperty('Link for Organisation', required=False)
  

class Controlled_Terminology_Source(db.Model):
  """
  Source for NCI Controlled Terminology
  """
  organisation = db.ReferenceProperty(Organisation, required=True)
  name = db.StringProperty('Source Name', required=True)
  description = db.StringProperty('Source Description', required=False)
  url = db.URLProperty('Source for Controlled Terminology (URL)', required=False)
  merge_date = db.DateProperty('Date of Merge', auto_now=True)
  
class CodedTerminology(polymodel.PolyModel):
  CodedTerminology_Type = db.StringProperty('Type of CT')
  Source = db.ReferenceProperty(Controlled_Terminology_Source, required=True)
  
class CDISC_ControlledTerminology(CodedTerminology):
  """
  Common Elements to both the CodeList and CodeListItem/EnumeratedItem
  """
  CodedTerminology_Type = 'CDISC Controlled Terminology'
  ExternalCodeID = db.StringProperty('NCI Code')
  CDISCSubmissionValue = db.StringProperty('CDISC Submission Value', required=True)
  CDISCSynonym = db.StringListProperty('CDISC Synonyms')
  CDISCDefinition = db.TextProperty('CDISC Definition')
  PreferredTerm = db.StringProperty('NCI Preferred Term')
  Draft  = db.BooleanProperty('Draft Controlled Terminology', default=False)
  Merge_Date = db.DateProperty('Date of Creation', auto_now_add=True)
  Modification_Date = db.DateProperty('Date of Modification', 
                                      auto_now=True)
  Created_by = db.UserProperty('Created By', auto_current_user_add=True)
  Modified_by = db.UserProperty('Created By', auto_current_user=True)

class CDISC_CodeListItem(CDISC_ControlledTerminology):
  """
  This is interesting - one code can be in many codelists
  - please note the disparity between the EnumeratedItem used
  by the CT XML group and the CodeListItem terminology used here
  """
  Codelists = db.ListProperty(db.Key)
  

class CDISC_Codelist(CDISC_ControlledTerminology):
  OID = db.StringProperty('OID')
  Extensible = db.BooleanProperty('Codelist is extensible?', default=True)
  Name = db.StringProperty('CodeList Name')
  DataType = db.StringProperty('DataType')

  @property
  def coded_items(self):
    return [x for x in CDISC_CodeListItem.gql("WHERE Codelists = :1" , self.key())]
  

class SimpleDataType(db.Model):
  # Organisation for the CT

  Source = db.ReferenceProperty(Controlled_Terminology_Source, required=True)

# ISO 21090 data types
class AbstractDataType(db.Model):
  """
  General Abstract DataType
  """
  Source = db.ReferenceProperty(Controlled_Terminology_Source, required=True)
  attributes = db.ListProperty(db.Key)

class AbstractDataType_Attribute(db.Model):
  """
  A dependent Property
  """
  name = db.StringProperty('Attribute Name')
  description = db.StringProperty('Attribute Description')
  datatype = db.ReferenceProperty(SimpleDataType)
  
class AbstractDataType_Constraint(db.Model):
  """
  A dependent Property
  """
  adt = db.ReferenceProperty(AbstractDataType)
  constraint_item = db.ReferenceProperty(AbstractDataType_Attribute, 'Applies to')
  constraint_detail = db.StringProperty('Constraint')

